package top.glkj.hms.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.glkj.hms.dao.RoleDao;
import top.glkj.hms.entity.Permission;
import top.glkj.hms.entity.Role;
import top.glkj.hms.exception.DefineException;
import top.glkj.hms.service.PermissionService;
import top.glkj.hms.service.RoleService;
import top.glkj.hms.utils.*;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

/**
 * @author : xgl
 * @version : 0.0.1
 * @date :2020/11/24 0:11
 */
@Service
@Slf4j
public class RoleServiceImpl implements RoleService {
    private final RoleDao roleDao;
    private final PermissionService permissionService;

    @Autowired
    public RoleServiceImpl(RoleDao roleDao, PermissionService permissionService) {
        this.roleDao = roleDao;
        this.permissionService = permissionService;
    }

    /**
     * 添加角色
     *
     * @param role 角色
     * @return 修改结果
     */
    @Override
    public Result addRole(Role role) {
        role.setCreateTime(new Date());
        role.setCreateUserId(getCurrentUser().getId());
        role.setUpdateTime(new Date());
        return save(role);
    }

    /**
     * 修改角色
     *
     * @param role 角色
     * @return 结果
     */
    @Override
    public Result updateRole(Role role) {
        role.setUpdateTime(new Date());

        return save(role);
    }

    /**
     * 获取所有用户，按分页方式
     *
     * @return List<T>
     */
    @Override
    public Result getAll() {
        List<Role> all = roleDao.findAll();
        if (all.size() == 0) {
            return ResultFactory.isError(StaticValue.DATA_NOT_FOUND, null);
        } else {
            return ResultFactory.isSuccess(StaticValue.GET_DATA_SUCCESS, all);
        }
    }

    /**
     * 获取所有用户，按分页方式
     *
     * @param id id
     * @return T t
     */
    @Override
    public Result getOne(Long id) {
        Role role = roleDao.findById(id).orElse(null);
        if (role == null) {
            return ResultFactory.isError(StaticValue.DATA_NOT_FOUND, null);
        } else {
            return ResultFactory.isSuccess(StaticValue.GET_DATA_SUCCESS, role);
        }
    }

    /**
     * 修改或者保存
     *
     * @param role T t
     * @return true or false
     */
    @Override
    public Result save(Role role) {
        try {
            Role save = roleDao.save(role);
            return ResultFactory.isSuccess(StaticValue.SUCCESS_MESSAGE, save);
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultFactory.isException(StaticValue.ERROR_MESSAGE, null);
        }
    }

    /**
     * 彻底从数据库中删除实体{T}
     *
     * @param role T t
     * @return true or false
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result delete(Role role) {
        try {
            roleDao.delete(role);
            return ResultFactory.isSuccess(StaticValue.DELETE_DATA_ERROR);
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultFactory.isError(StaticValue.ERROR_MESSAGE);
        }
    }

    /**
     * 标记删除
     *
     * @param role T t
     * @return true or false
     */
    @Override
    public Result remove(Role role) {
        role.setDel(true);
        role.setStatus(Status.Delete);
        Result save = save(role);
        if (ResultFactory.isSuccess(save)) {
            return ResultFactory.isSuccess(StaticValue.DELETE_DATA_SUCCESS, save);
        } else {
            return ResultFactory.isException(StaticValue.DELETE_DATA_ERROR);
        }
    }

    /**
     * 分页查询
     *
     * @param page 当前页码
     * @param size 页面大小
     * @return page Role
     */
    @Override
    public Result getRolesByPageAndSize(int page, int size) {
        GlUtils<Role, RoleDao> glUtils = new GlUtils<>();
        return glUtils.getAllByPageAndSize(page, size, roleDao);
    }

    /**
     * 分页条件查询
     *
     * @param page    当前页码
     * @param size    页面大小
     * @param argName 参数名
     * @param value   参数值
     * @return page User
     */
    @Override
    public Result getAllRolesByPageAndSizeAndArgs(int page, int size, String argName, String value) {
        GlUtils<Role, RoleDao> glUtils = new GlUtils<>();
        return glUtils.getAllByPageAndSizeAndArgs(page, size, argName, value, roleDao);
    }

    /**
     * 分页查询
     *
     * @param page 当前页码
     * @param size 页面大小
     * @param args 参数键值对
     * @return page User
     */
    @Override
    public Result getAllRolesByPageAndSizeAndAnyArgs(int page, int size, Map<String, String> args) {
        GlUtils<Role, RoleDao> glUtils = new GlUtils<>();
        return glUtils.getAllByPageAndSizeAndAnyArgs(page, size, args, roleDao);
    }

    /**
     * 角色添加权限
     *
     * @param rid     角色id
     * @param pidList 权限id列表
     * @return 结果
     */
    @Override
    public Result roleAddPermissions(long rid, List<Long> pidList) throws DefineException {
        Result one = getOne(rid);
        if (ResultFactory.isSuccess(one)) {
            Role role = (Role) one.getObject();
            HashSet<Permission> permissions = new HashSet<>();
            for (long pid : pidList) {
                Result one1 = permissionService.getOne(pid);
                if (ResultFactory.isSuccess(one1)) {
                    role.getPermissions().add((Permission) one1.getObject());
                } else {
                    throw new DefineException(StaticValue.NOT_ROLE_DATA);
                }
            }
            return save(role);
        } else {
            return one;
        }
    }

    /**
     * 角色修改权限
     *
     * @param rid     角色id
     * @param pidList 权限id列表
     * @return 结果
     * @throws DefineException e
     */
    @Override
    public Result roleUpdatePermissions(long rid, List<Long> pidList) throws DefineException {
        Result one = getOne(rid);
        if (ResultFactory.isSuccess(one)) {
            Role role = (Role) one.getObject();
            HashSet<Permission> permissions = new HashSet<>();
            for (long pid : pidList) {
                Result one1 = permissionService.getOne(pid);
                if (ResultFactory.isSuccess(one1)) {
                    permissions.add((Permission) one1.getObject());
                } else {
                    throw new DefineException(StaticValue.NOT_ROLE_DATA);
                }
            }
            role.setPermissions(permissions);
            return save(role);
        } else {
            return one;
        }
    }

    /**
     * 角色移除权限
     *
     * @param rid     角色id
     * @param pidList 移除id列表
     * @return 结果
     */
    @Override
    public Result roleDeletePermissions(long rid, List<Long> pidList) throws DefineException {
        Result one = getOne(rid);
        if (ResultFactory.isSuccess(one)) {
            Role role = (Role) one.getObject();
            HashSet<Permission> permissions = new HashSet<>();
            for (long pid : pidList) {
                Result one1 = permissionService.getOne(pid);
                if (ResultFactory.isSuccess(one1)) {
                    permissions.remove((Permission) one1.getObject());
                } else {
                    throw new DefineException(StaticValue.NOT_ROLE_DATA);
                }
            }
            role.setPermissions(permissions);
            return save(role);
        } else {
            return one;
        }
    }

    /**
     * 根据角色名称获取角色id
     *
     * @param name 角色名称
     * @return 角色
     */
    @Override
    public Result getRoleByName(String name) {
        Role role = roleDao.findRoleByRoleName(name);
        if (role == null) {
            return ResultFactory.isError(StaticValue.DATA_NOT_FOUND, null);
        } else {
            return ResultFactory.isSuccess(StaticValue.GET_DATA_SUCCESS, role);
        }
    }
}
